home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Synth / Envelope.C < prev    next >
C/C++ Source or Header  |  2005-03-14  |  4KB  |  166 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   Envelope.C - Envelope implementation
  5.   Copyright (C) 2002-2005 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20.  
  21. */
  22.  
  23. #include <stdio.h>
  24. #include "Envelope.h"
  25.  
  26. Envelope::Envelope(EnvelopeParams *envpars,REALTYPE basefreq){
  27.     int i;
  28.     envpoints=envpars->Penvpoints;
  29.     if (envpoints>MAX_ENVELOPE_POINTS) envpoints=MAX_ENVELOPE_POINTS;
  30.     envsustain=(envpars->Penvsustain==0)?-1:envpars->Penvsustain;
  31.     forcedrelase=envpars->Pforcedrelease;
  32.     envstretch=pow(440.0/basefreq,envpars->Penvstretch/64.0);
  33.     linearenvelope=envpars->Plinearenvelope;
  34.  
  35.     if (envpars->Pfreemode==0) envpars->converttofree();
  36.     
  37.     REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE;
  38.  
  39.     int mode=envpars->Envmode;
  40.  
  41.     //for amplitude envelopes
  42.     if ((mode==1)&&(linearenvelope==0)) mode=2;//change to log envelope
  43.     if ((mode==2)&&(linearenvelope!=0)) mode=1;//change to linear
  44.  
  45.     for (i=0;i<MAX_ENVELOPE_POINTS;i++) {
  46.         REALTYPE tmp=envpars->getdt(i)/1000.0*envstretch;
  47.     if (tmp>bufferdt) envdt[i]=bufferdt/tmp;
  48.         else envdt[i]=2.0;//any value larger than 1
  49.  
  50.     switch (mode){
  51.         case 2:envval[i]=(1.0-envpars->Penvval[i]/127.0)*MIN_ENVELOPE_DB;
  52.            break;
  53.         case 3:envval[i]=(pow(2,6.0*fabs(envpars->Penvval[i]-64.0)/64.0)-1.0)*100.0;
  54.            if (envpars->Penvval[i]<64) envval[i]=-envval[i];
  55.            break;
  56.         case 4:envval[i]=(envpars->Penvval[i]-64.0)/64.0*6.0;//6 octaves (filtru)
  57.            break;
  58.         case 5:envval[i]=(envpars->Penvval[i]-64.0)/64.0*10;
  59.            break;
  60.         default:envval[i]=envpars->Penvval[i]/127.0;
  61.     };
  62.     
  63.     };
  64.  
  65.     envdt[0]=1.0;
  66.  
  67.     currentpoint=1;//the envelope starts from 1
  68.     keyreleased=0;
  69.     t=0.0;
  70.     envfinish=0;
  71.     inct=envdt[1];
  72.     envoutval=0.0;
  73. };
  74.  
  75. Envelope::~Envelope(){
  76. };
  77.  
  78.  
  79. /*
  80.  * Relase the key (note envelope)
  81.  */
  82. void Envelope::relasekey(){
  83.     if (keyreleased==1) return;
  84.     keyreleased=1;
  85.     if (forcedrelase!=0) t=0.0;
  86. };
  87.  
  88. /*
  89.  * Envelope Output
  90.  */
  91. REALTYPE Envelope::envout(){
  92.     REALTYPE out;
  93.  
  94.     if (envfinish!=0) {//if the envelope is finished
  95.     envoutval=envval[envpoints-1];
  96.     return(envoutval);
  97.     };
  98.     if ((currentpoint==envsustain+1)&&(keyreleased==0)) {//if it is sustaining now
  99.     envoutval=envval[envsustain];
  100.     return(envoutval);
  101.     };
  102.  
  103.     if ((keyreleased!=0) && (forcedrelase!=0)){//do the forced release    
  104.     
  105.         int tmp=(envsustain<0) ? (envpoints-1):(envsustain+1);//if there is no sustain point, use the last point for release
  106.  
  107.     if (envdt[tmp]<0.00000001) out=envval[tmp];
  108.             else out=envoutval+(envval[tmp]-envoutval)*t;
  109.     t+=envdt[tmp]*envstretch;
  110.  
  111.     if (t>=1.0) {
  112.                currentpoint=envsustain+2;
  113.            forcedrelase=0;
  114.            t=0.0;
  115.            inct=envdt[currentpoint];
  116.            if ((currentpoint>=envpoints)||(envsustain<0)) envfinish=1;
  117.         };
  118.     return(out);
  119.     };
  120.     if (inct>=1.0) out=envval[currentpoint];
  121.     else out=envval[currentpoint-1]+(envval[currentpoint]-envval[currentpoint-1])*t;
  122.  
  123.     t+=inct;
  124.     if (t>=1.0){
  125.     if (currentpoint>=envpoints-1) envfinish=1;
  126.         else currentpoint++;
  127.     t=0.0;
  128.     inct=envdt[currentpoint];
  129.     };
  130.  
  131.     envoutval=out;    
  132.     return (out);
  133. };
  134.  
  135. /*
  136.  * Envelope Output (dB)
  137.  */
  138. REALTYPE Envelope::envout_dB(){
  139.     REALTYPE out;
  140.     if (linearenvelope!=0) return (envout());
  141.     
  142.     if ((currentpoint==1)&&((keyreleased==0)||(forcedrelase==0))) {//first point is always lineary interpolated
  143.     REALTYPE v1=dB2rap(envval[0]);
  144.     REALTYPE v2=dB2rap(envval[1]);
  145.     out=v1+(v2-v1)*t;
  146.     
  147.     t+=inct; 
  148.     if (t>=1.0) {
  149.         t=0.0;
  150.         inct=envdt[2];
  151.         currentpoint++;
  152.         out=v2;
  153.     };
  154.     
  155.     if (out>0.001) envoutval=rap2dB(out);
  156.         else envoutval=-40.0;
  157.     } else out=dB2rap(envout());
  158.  
  159.     return(out);
  160. };
  161.  
  162. int Envelope::finished(){
  163.     return(envfinish);
  164. };
  165.  
  166.